package com.zhiwang.planet.ui.webview_ultimate;

import com.zhiwang.planet.ui.webview_ultimate.interceptors.ConsoleInterceptor;
import com.zhiwang.planet.ui.webview_ultimate.interceptors.DwInterceptor;
import com.zhiwang.planet.ui.webview_ultimate.interceptors.InitLoadInterceptor;
import com.zhiwang.planet.ui.webview_ultimate.interceptors.LegacyInterceptor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

public class WebViewInterceptorHelper extends InterceptorAdapter implements InvocationHandler {


    private List<Interceptor> interceptors = new ArrayList<>();


    {
        addInterceptor(new ConsoleInterceptor());
        addInterceptor(new DwInterceptor());
        addInterceptor(new InitLoadInterceptor());
        addInterceptor(new LegacyInterceptor());

    }


    private void addInterceptor(Interceptor interceptor) {
        interceptors.add(interceptor);
    }


    public static Interceptor get() {

        return (Interceptor) Proxy.newProxyInstance(
                Interceptor.class.getClassLoader(),
                new Class[]{Interceptor.class},
                new WebViewInterceptorHelper());
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //依次处理所有的拦截器

        boolean intercept = false;


        for (Interceptor interceptor : interceptors) {

            if (method.getGenericReturnType() == void.class) {
                method.invoke(interceptor, args);
            } else if (method.getAnnotation(Interceptable.class) != null) {

                intercept = true;
                if (method.getGenericReturnType() != boolean.class)
                    throw new IllegalStateException(
                            "Interceptable 注解的方法必须返回 boolean 类型"
                                    + "以确定是否需要中断后面的请求  " + method + "(" + method.getParameterTypes() + ")");


                boolean r = (boolean) method.invoke(interceptor, args);

                if (r) return true;

            } else {
                return method.invoke(interceptor, args);
            }
        }


        if (intercept)
            return false;

        return null;

    }
}
